package com.yys.excel.yysexcel.mapper;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.IterUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TimeInterval;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.db.Entity;
import cn.hutool.json.JSONUtil;
import com.yys.excel.yysexcel.common.constant.ExcelStants;
import com.yys.excel.yysexcel.common.enums.ErrorStatus;
import com.yys.excel.yysexcel.common.exception.CustomException;
import com.yys.excel.yysexcel.common.exception.ServiceException;
import com.yys.excel.yysexcel.entity.ImportExportTask;
import com.yys.excel.yysexcel.entity.ImportExportTemplate;
import com.yys.excel.yysexcel.entity.JdbcConfig;
import com.yys.excel.yysexcel.entity.entityBo.ImportExportParamBo;
import com.yys.excel.yysexcel.utils.RandomStrg;
import com.yys.excel.yysexcel.utils.dbUtil.DbUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 注释
 *
 * @author lys
 * @date 2022/11/29
 */
public class ImportExportMapper {
    /**
     * 通过id获取实体
     *
     * @param tableName 表名
     * @param id        id
     * @return {@link Entity}
     */
    public static Entity getEntityById(String tableName, String id) {
        String sql = StrUtil.format("select * from {} where isdelete = 0 and id = '{}'", tableName, id);
        return DbUtil.query(sql);
    }

    /**
     * 获取表数据
     *
     * @param tableName 表名
     * @return {@link List}<{@link Entity}>
     */
    public static List<Entity> getEntitys(String tableName) {
        String sql = StrUtil.format("select * from {} where isdelete = 0", tableName);
        return DbUtil.querys(sql);
    }

    /**
     * 根据模板id 获取jdbc
     *
     * @param templateId 模板id
     * @return {@link JdbcConfig}
     */
    public static JdbcConfig getJdbcByTemplateId(String templateId) {
        try {
            ImportExportTemplate templet = getTemplateById(templateId);
            String jdbcConfigId = templet.getJdbc_config_id();
            return getJdbcConfigById(jdbcConfigId);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 插入模板
     *
     * @param importExportTemplate 导入导出模板
     * @return int
     */
    public static int insertTemplate(ImportExportTemplate importExportTemplate) {
        Entity entity = BeanUtil.toBean(importExportTemplate, Entity.class).setTableName(ImportExportTemplate.getTableName());
        //主键自增，删除id
        entity.remove("id");
        return DbUtil.insert(entity);
    }

    /**
     * 插入task
     *
     * @param importExportTask 任务
     * @return int
     */
    public static int insertTask(ImportExportTask importExportTask) {
        Entity entity = BeanUtil.toBean(importExportTask, Entity.class).setTableName(ImportExportTask.getTableName());
        return DbUtil.insert(entity);
    }

    /**
     * 插入jdbc
     *
     * @param jdbcConfig 数据库连接配置
     * @return int
     */
    public static int insertJdbc(JdbcConfig jdbcConfig) {
        Entity entity = BeanUtil.toBean(jdbcConfig, Entity.class).setTableName(JdbcConfig.getTableName());
        return DbUtil.insert(entity);
    }

    public static void main(String[] args) {
        ImportExportTask dsf = getImportExportTaskById("dsf");
        System.out.println();
    }

    /**
     * 通过id获取模板
     *
     * @param id id
     * @return {@link ImportExportTemplate}
     */
    public static ImportExportTemplate getTemplateById(String id) {
        Entity entity = getEntityById(ImportExportTemplate.getTableName(), id);
        if (null == entity) {
            return null;
        }
        return entity.toBean(ImportExportTemplate.class);
    }

    /**
     * 通过id数据库连接配置
     *
     * @param id id
     * @return {@link JdbcConfig}
     */
    public static JdbcConfig getJdbcConfigById(String id) {
        Entity entity = getEntityById(JdbcConfig.getTableName(), id);
        if (null == entity) {
            return null;
        }
        return entity.toBean(JdbcConfig.class);
    }

    /**
     * 通过id获取任务
     *
     * @param id id
     * @return {@link JdbcConfig}
     */
    public static ImportExportTask getImportExportTaskById(String id) {
        Entity entity = getEntityById(ImportExportTask.getTableName(), id);
        if (null == entity) {
            return null;
        }
        return entity.toBean(ImportExportTask.class);
    }

    /**
     * 更新任务id
     * 注：如果属性为空，会将原有数据设置为空
     *
     * @param task 任务
     * @return int
     */
    public static int updateTaskById(ImportExportTask task) {
        Entity entity = BeanUtil.toBean(task, Entity.class).setTableName(ImportExportTask.getTableName());
        //记录数据库
        return DbUtil.update(entity, Entity.create().set("id", task.getId()));
    }

    /**
     * 更新jdbc
     * 注：如果属性为空，会将原有数据设置为空
     *
     * @param jdbcConfig
     * @return int
     */
    public static int updateJdbcConfigById(JdbcConfig jdbcConfig) {
        Entity entity = BeanUtil.toBean(jdbcConfig, Entity.class).setTableName(JdbcConfig.getTableName());
        //记录数据库
        return DbUtil.update(entity, Entity.create().set("id", jdbcConfig.getId()));
    }

    /**
     * 更新template
     * 注：如果属性为空，会将原有数据设置为空
     *
     * @param template
     * @return int
     */
    public static int updateImportExportTemplateById(ImportExportTemplate template) {
        Entity entity = BeanUtil.toBean(template, Entity.class).setTableName(ImportExportTemplate.getTableName());
        //记录数据库
        return DbUtil.update(entity, Entity.create().set("id", template.getId()));
    }

    /**
     * 封装异常时插入异常消息(异常结束)
     *
     * @param id     数据id
     * @param msg    异常消息
     * @param status 异常类型   -1异常 -2超时 -3主动终止 0等待执行 1执行中 2执行完成
     * @param timer  计时器
     */
    public static void opError(String id, String msg, int status, TimeInterval timer) {
        Entity e = Entity.create(ImportExportTask.getTableName()).set("op_error", msg).set("update_time", DateUtil.now())
                .set("status", status).set("execute_time", timer.intervalSecond());
        //记录数据库
        DbUtil.update(e, Entity.create().set("id", id));
        throw new CustomException(msg);
    }

    /**
     * 更新任务op文件名
     *
     * @param id         id
     * @param OpFileName op文件名
     * @return int
     */
    public static int updateTaskOpFileName(String id, String OpFileName) {
        Entity e = Entity.create(ImportExportTask.getTableName()).set("op_file_name", OpFileName);
        //记录数据库
        return DbUtil.update(e, Entity.create().set("id", id));
    }

    /**
     * 更新任务状态
     *
     * @param id     id
     * @param status 状态
     * @return int
     */
    public static int updateTaskStatus(String id, int status,ImportExportParamBo importExportParamBo) {
        Entity e = Entity.create(ImportExportTask.getTableName()).set("status", status);
        if(null != importExportParamBo){
            String parameters = beanToMapRemoveKey(importExportParamBo);
            e.set("parameters",parameters);
        }
        setSystemByTemplateId(importExportParamBo, e);
        return DbUtil.update(e, Entity.create().set("id", id));
    }

    /**
     * 更新任务结束
     *
     * @return int
     */
    public static int updateTaskEnd(String id, long second, String msg,String filePath) {
        //插入成功后记录入库
        Entity e = Entity.create(ExcelStants.IMPORT_EXPORT_TASK_TABLE).set("update_time", DateUtil.now())
                .set("execute_time", second)
                .set("status", ErrorStatus.EXECUTOVER.getCode()).set("op_error", msg);
        if(StrUtil.isNotBlank(filePath)){
            e.set("op_file_name",filePath);
        }
        //记录数据库
        return DbUtil.update(e, Entity.create().set("id", id));
    }

    /**
     * 插入任务导入
     *
     * @param importExportParamBo 进出口参数波
     */
    public static String insertTaskImport(ImportExportParamBo importExportParamBo) {
        String id = RandomStrg.getGUID32();
        String parameters = beanToMapRemoveKey(importExportParamBo);
        Entity entity = Entity.create(ExcelStants.IMPORT_EXPORT_TASK_TABLE).set("id", id)
                .set("status", ErrorStatus.WAITEXECUTE.getCode()).set("op_type", "import").set("op_async", 1).set("system", importExportParamBo.getSystem())
                .set("create_time", DateUtil.now()).set("op_file_type", importExportParamBo.getFileType()).set("create_by", importExportParamBo.getCreateBy())
                .set("parameters", parameters).set("template_id", importExportParamBo.getTemplateId());
        //记录数据库
        setSystemByTemplateId(importExportParamBo, entity);
        DbUtil.insert(entity);
        return id;
    }

    /**
     * 更新进度
     *
     * @return int
     */
    public static int updateProgress(String id, long progress, String unit, long second) {
        Entity e = Entity.create(ExcelStants.IMPORT_EXPORT_TASK_TABLE).set("update_time", DateUtil.now())
                .set("progress", progress + unit).set("execute_time", second);
        return DbUtil.update(e, Entity.create().set("id", id));
    }

    /**
     * 插入导出任务
     *
     * @param importExportParamBo 进出口参数波
     * @return int
     */
    public static String insertExportTask(ImportExportParamBo importExportParamBo) {
        String id = RandomStrg.getGUID32();
        String parameters = beanToMapRemoveKey(importExportParamBo);
        Entity entity = Entity.create(ExcelStants.IMPORT_EXPORT_TASK_TABLE).set("id", id).set("sqls", importExportParamBo.getSql())
                .set("status", ErrorStatus.WAITEXECUTE.getCode()).set("op_type", "export").set("op_async", 1).set("system", importExportParamBo.getSystem())
                .set("create_time", DateUtil.now()).set("op_file_type", "xlsx").set("create_by", importExportParamBo.getCreateBy())
                .set("parameters", parameters).set("template_id", importExportParamBo.getTemplateId());
        //记录数据库
        setSystemByTemplateId(importExportParamBo, entity);
        DbUtil.insert(entity);
        return id;
    }

    /**
     * 更新任务模板
     *
     * @param id         id
     * @param templateId 模板id
     * @return int
     */
    public static int updateTaskTemplate(String id, String templateId) {
        return DbUtil.update(Entity.create(ExcelStants.IMPORT_EXPORT_TASK_TABLE).set("template_id", templateId), Entity.create().set("id", id));
    }

    /**
     * 获取正在执行和未执行的任务
     *
     * @return {@link List}<{@link ImportExportTask}>
     */
    public static List<ImportExportTask> getNotExecute(){
        List<Entity> datas = DbUtil.querys(StrUtil.format("select * from {} where isdelete=0 and status in('{}','{}') order by create_time desc",
                ExcelStants.IMPORT_EXPORT_TASK_TABLE,ErrorStatus.WAITEXECUTE.getCode(),ErrorStatus.EXECUTING.getCode()));
        if(IterUtil.isNotEmpty(datas)){
            return datas.stream().map(e->e.toBean(ImportExportTask.class)).collect(Collectors.toList());
        }
        return new ArrayList<>();
    }

    /**
     * 设置系统 根据模板id
     *
     * @param importExportParamBo 进出口参数波
     * @param e                任务
     */
    public static void setSystemByTemplateId(ImportExportParamBo importExportParamBo, Entity e) {
        if(ObjectUtil.isEmpty(importExportParamBo)){
            return;
        }
        String templateId = importExportParamBo.getTemplateId();
        JdbcConfig jdbcConfig = getJdbcByTemplateId(templateId);
        if(ObjectUtil.isNotEmpty(e)){
            e.set("system",jdbcConfig.getDatabase_name());
        }
    }

    /**
     * 实体类转map并删除file和流
     *
     * @param importExportParamBo 进出口参数波
     * @return {@link String}
     */
    public static String beanToMapRemoveKey(ImportExportParamBo importExportParamBo) {
        String jsonStr = "";
        try {
            Map<String, Object> res = BeanUtil.beanToMap(importExportParamBo, false, true);
            res.remove("file");
            res.remove("inputStream");
            jsonStr = JSONUtil.toJsonStr(res);
        }catch (Exception e){
            throw new ServiceException(ErrorStatus.EXCEPTION.getCode(),"参数转json出错：" + e.getMessage());
        }
        return jsonStr;
    }
}
